# 单例模式1
# 类的方式写一个单例
# 类的方式 自定义元类 方法执行顺序：
# python自上而下的，先执行SingleMetaClass.__init__
# 然后到入口函数这里 p1 = SinglePerson() 实例化类对象 执行__cal__函数，进行初始化单例
class SingleMetaClass(type):

    def __init__(cls, *args, **kwargs):
        print('第二步：__init__')
        cls._instance = None
        super().__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        print('第三步：__call__')
        if not cls._instance:
            cls._instance = super().__call__(*args, **kwargs)
        return cls._instance

    def __str__(self):
        print('__str__')
        return super().__str__()

    def __new__(cls, name, bases, attrs):
        print('第一步：__new__')
        return super().__new__(cls, name, bases, attrs)


class SinglePerson(object, metaclass=SingleMetaClass):
    pass


if __name__ == '__main__':
    p1 = SinglePerson()  # 执行这步时执行__cal__函数，进行初始化单例
    # p1 实例化的时候，先调用 __new__ 私有函数
    print(p1)

    p2 = SinglePerson()
    #
    # # is 比较的是内存中是不是一个对象，内存地址是否一样
    print(p1 is p2)  # True
    # #
    print(p1, p2)
    print(p1._instance)
    # <__main__.SinglePerson object at 0x0000016EC64D58E0>
    # <__main__.SinglePerson object at 0x0000016EC64D58E0>
